/*
 * @Author: 0x9DEFA478
 * @Date: 2025-06-28 14:34:39
 * @LastEditTime: 2025-07-27 22:32:56
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * 
 */
#ifndef hhmkdecode_HPP_
#define hhmkdecode_HPP_
#include <string>
#include <sstream>
#include <vector>
#include "H_Pointer.hpp"


namespace HMake{

  
  class HMK_Element{
    public:
      using Pointer=H::Pointer<HMK_Element>;

      enum class Type:int{

        //基础元素
        BaseStartIndex_=0,
        Text=BaseStartIndex_+0,
        ValueMark=BaseStartIndex_+1,
        BracketBegin=BaseStartIndex_+2,
        BracketEnd=BaseStartIndex_+3,
        Comma=BaseStartIndex_+4,
        Colon=BaseStartIndex_+5,
        String=BaseStartIndex_+6,
        NewLine=BaseStartIndex_+7,
        BaseEnd_=BaseStartIndex_+8,

        //算数赋值
        EqualStartIndex_=BaseEnd_,
        Equal=EqualStartIndex_+0,
        EqualSelfAdd=EqualStartIndex_+1,
        EqualSelfSub=EqualStartIndex_+2,
        EqualEnd_=EqualStartIndex_+3,

        //算数运算
        ArithmeticStartIndex_=EqualEnd_,
        Add=ArithmeticStartIndex_+0,
        Sub=ArithmeticStartIndex_+1,
        ArithmeticEnd_=ArithmeticStartIndex_+2

      };

    public:

      HMK_Element(Type type,int line,int pos)noexcept:type_(type),line_(line),pos_(pos){}
      virtual ~HMK_Element(){}

      Type type()const{return type_;}
      int line()const{return line_;}
      int pos()const{return pos_;}

      static const char* TypeToString(Type type);

      static std::vector<Pointer> decode(const std::string& path);

    private:
      Type type_;
      int line_;
      int pos_;

  };

  class HMK_Element_Text:public HMK_Element{

    public:
      HMK_Element_Text(int line,int pos)noexcept:HMK_Element(Type::Text,line,pos){
      }

      HMK_Element_Text& operator<<(auto value){
        ss<<value;
        return *this;
      }

      std::string Text()const{return ss.str();}

    private:
      std::stringstream ss;
  };

  class HMK_Element_String:public HMK_Element{

    public:
      HMK_Element_String(const std::string s,int line,int pos)noexcept:HMK_Element(Type::String,line,pos),s(s){
      }

      std::string str()const{return s;}

    private:
      std::string s;
  };


  class Expression{
    public:
      using Pointer=H::Pointer<Expression>;

      enum class Type:int{

        //基础元素
        BaseStartIndex_=0,
        Collection=BaseStartIndex_+0,
        Text=BaseStartIndex_+1,
        ValueMark=BaseStartIndex_+2,
        String=BaseStartIndex_+3,
        BaseEnd_=BaseStartIndex_+4,

        //算数
        OperatorStartIndex_=BaseEnd_,
        Assignment=OperatorStartIndex_+0,//赋值运算
        Arithmetic=OperatorStartIndex_+1,//运算
        OperatorEnd_=OperatorStartIndex_+2

      };

    public:

      Expression(Type type,int line,int pos)noexcept:type_(type),line_(line),pos_(pos){}
      virtual ~Expression(){}

      Type type()const{return type_;}
      int line()const{return line_;}
      int pos()const{return pos_;}
      bool IsOper()const{return (type_>=Type::OperatorStartIndex_)&&(type_<Type::OperatorEnd_);}

      static const char* TypeToString(Type type);

      static std::vector<Pointer> decode(const std::string& path,const std::vector<HMK_Element::Pointer>& element0);

      template<typename Target_T>
      Target_T* ToType(){return static_cast<Target_T*>(this);}

      template<typename Target_T>
      const Target_T* ToType()const{return static_cast<const Target_T*>(this);}

    private:
    
      static Pointer decodeExpression(const std::string& path,const std::vector<HMK_Element::Pointer>& expression,std::size_t Index,std::size_t Count);

      static void decodeOperator(const std::string& path,Pointer& Expression);
      static void decodePriority(const std::string& path,Pointer& Expression);

    private:

      Type type_;
      int line_;
      int pos_;

  };

  class Expression_Collection:public Expression{
    public:
      Expression_Collection(char beginChar,int line,int pos):Expression(Type::Collection,line,pos),beginChar(beginChar){}

      const std::vector<Pointer>& Colloection()const{return colloection;}
      std::vector<Pointer>& Colloection(){return colloection;}
      char BeginChar()const{return beginChar;}
      void AddElement(Pointer& pointer){colloection.emplace_back(pointer);}
      void AddElement(Pointer&& pointer){colloection.emplace_back(pointer);}

    private:
      std::vector<Pointer> colloection;
      char beginChar;
  };

  class Expression_Text:public Expression{
    public:
      explicit Expression_Text(const HMK_Element_Text* element):Expression(Type::Text,element->line(),element->pos()){
        text=element->Text();
      }

      const std::string& Text()const{return text;}

    private:
      std::string text;
  };

  class Expression_String:public Expression{
    public:
      explicit Expression_String(const HMK_Element_String* element):Expression(Type::String,element->line(),element->pos()){
        s=element->str();
      }

      const std::string& str()const{return s;}

    private:
      std::string s;
  };

  class Expression_Operator:public Expression{
    public:
      explicit Expression_Operator(Type type,int line,int pos,char Operator):Expression(type,line,pos),operator_(Operator){}

      char Operator()const{return operator_;}

      int32_t Priority()const;

    private:
      char operator_;
  };


}


#endif //hhmkdecode_HPP_
